// quote from "Adding a New Protocol to Mozilla" http://nexgenmedia.net/docs/protocol/

// Test protocol related
const kSCHEME = "xmpp";
const kPROTOCOL_NAME = "XMPP Protocol";
const kPROTOCOL_CONTRACTID = "@mozilla.org/network/protocol;1?name=" + kSCHEME;
// NOTE: You have to generate a new UUID(GUID) for each protocols you want to implement.
//       Please don't copy a following line.
const kPROTOCOL_CID = Components.ID("f6cb8fd0-ef54-11dd-ba2f-0800200c9a67");

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const IOService = Cc["@mozilla.org/network/io-service;1"].
                    getService(Ci.nsIIOService);
const WindowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
                         getService(Ci.nsIWindowMediator);

/**
 * JS XPCOM component registration goop:
 *
 * We set ourselves up to observe the xpcom-startup category.  This provides
 * us with a starting point.
 */

var TestModule = {
  registerSelf: function testModuleRegisterSelf(aCompMgr, aFileSpec, aLocation, aType) {
    aCompMgr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
    aCompMgr.registerFactoryLocation(kPROTOCOL_CID,
                                     kPROTOCOL_NAME,
                                     kPROTOCOL_CONTRACTID,
                                     aFileSpec,
                                     aLocation,
                                     aType);
  },
  getClassObject: function testModuleGetClassObject(aCompMgr, aCid, aIid) {
    if (!aCid.equals(kPROTOCOL_CID))
      throw Cr.NS_ERROR_NO_INTERFACE;

    if (!aIid.equals(Ci.nsIFactory))
      throw Cr.NS_ERROR_NOT_IMPLEMENTED;

    return ProtocolFactory;
  },
  canUnload: function testModuleCanUnload(aCompMgr) {
    return true;
  }
};

function NSGetModule(){
  return TestModule;
}

var ProtocolFactory = {
  createInstance: function protocolFactoryCreateInstance(aOuter, aIid) {
    if (aOuter != null)
      throw Cr.NS_ERROR_NO_AGGREGATION;

    if (!aIid.equals(Ci.nsIProtocolHandler) &&
        !aIid.equals(Ci.nsISupports))
      throw Cr.NS_ERROR_NO_INTERFACE;

    return new Protocol();
  }
};

function Protocol() {
}

Protocol.prototype = {
  scheme: kSCHEME,
  defaultPort: -1,
  protocolFlags: Ci.nsIProtocolHandler.URI_NOAUTH | Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE,
  QueryInterface: function (aIid) {
    if (!aIid.equals(Ci.nsIProtocolHandler) &&
        !aIid.equals(Ci.nsISupports))
      throw Cr.NS_ERROR_NO_INTERFACE;
    return this;
  },
  allowPort: function (aPort, aScheme) {
    return false;
  },
  newURI: function (aSpec, aCharset, aBaseURI) {
    var temp = Cc["@mozilla.org/network/standard-url;1"]
                .createInstance(Ci.nsIStandardURL);
    var m = /href;url=(.*)$/.exec(aBaseURI ? aBaseURI.spec : aSpec);
    if (m) {
      aBaseURI = IOService.newURI(m[1], null, null);
    }
    temp.init(1, -1, aSpec, aCharset, aBaseURI);
    temp.QueryInterface(Ci.nsIURI);

    m = /^xmpp:\/\/(.*)/.exec(temp.spec);
    if (m) {
      var uri = Cc["@mozilla.org/network/simple-uri;1"].
                  createInstance(Ci.nsIURI);
      if (/^xmpp:\/\/[^\/\?#]+\/[^\/\?#]+/.test(temp.spec)) {
        uri.spec = temp.spec;
      } else {
        uri.spec = "xmpp:" + m[1];
      }
      return uri;
    }
    return temp;
  },
  newChannel: function(aURI) {
    var topwin = WindowMediator.getMostRecentWindow("navigator:browser");
    var userBar   = topwin.document.getElementById("musubi-userbar");
    var sendtoBar = topwin.document.getElementById("musubi-sendtobar");
    var urlBar    = topwin.document.getElementById("musubi-urlbar");
    [userBar.value, sendtoBar.value, urlBar.value] = parseLocationHref(aURI.spec);
    return IOService.newChannel(urlBar.value, null, null);
  }
};

function parseLocationHref(aURISpec) {
  var m = null;
  var reXmppSlashSlashUserSendto = /^xmpp:\/\/([^\/\?#]+)\/([^\/\?#]+)/;
  m = reXmppSlashSlashUserSendto.exec(aURISpec);
  var user   = "";
  var sendto = "";
  var url    = "http://www.yahoo.co.jp/";
  if (m) {
    user   = m[1];
    sendto = m[2];
  } else {
    var reXmppColon = /^xmpp:([^\/\?#]+)/;
    m = reXmppColon.exec(aURISpec);
    if (m) {
      switch (adhocGetProfileName()) {
      case "xmppweb":
        user = "romeo@localhost";
        break;
      case "xmppweb2":
        user = "juliet@localhost";
        break;
      default:
        user = "default@localhost";
        break;
      }
      sendto = m[1];
    }
  }
  m = /href;url=(.*)$/.exec(aURISpec);
  if (m) url = m[1];
  return [user, sendto, url];
}

function adhocGetProfileName() {
  var DirectoryService = Cc["@mozilla.org/file/directory_service;1"].
                           getService(Ci.nsIProperties);
  var path = DirectoryService.get("ProfD", Ci.nsIFile).path;
  var arr = path.split(".");
  return arr[arr.length - 1];
}
